#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Verifier.h"
#include <string>
#include <vector>

#include "types.h"

#include <memory>

/// 语法树节点基类
class Node {
public:
  virtual ~Node() = default;

  /// 解析语法树方法
  static std::unique_ptr<Node> parseAST();

  virtual llvm::Value *codegen() = 0;
};
/// BinaryExpression(+,1, BinaryExpression(*, I32Expression(2),
/// I32Expression(3)))
/// BinaryExpression(*,BracketExpression(BinaryExpression(+,1,2)),3)
/// 解析AST方法
std::unique_ptr<std::vector<std::unique_ptr<Node>>> parseAST(std::string code);

/// 表达式节点基类
class Expression : public Node {

public:
  /// 解析语法树方法
  static std::unique_ptr<Expression> parseAST();
};

/// 布尔型表达式
class BooleanExpression : public Expression {
public:
  /// 当前值
  bool value;
};

/// 整数表达式
class IntegerExpression : public Expression {};

class I8Expression : public IntegerExpression {
public:
  I8Expression(char value) : value(value) {}

  char value;
};

class U8Expression : public IntegerExpression {
public:
  U8Expression(char value) : value(value) {}
  char value;
};

class I16Expression : public IntegerExpression {
public:
  I16Expression(short value) : value(value) {}
  short value;
};

class U16Expression : public IntegerExpression {
public:
  U16Expression(unsigned short value) : value(value) {}
  unsigned short value;
};

class I32Expression : public IntegerExpression {
public:
  I32Expression(int value) : value(value) {}
  int value;
};

class U32Expression : public IntegerExpression {
public:
  U32Expression(unsigned int value) : value(value) {}
  unsigned int value;
};

class I64Expression : public IntegerExpression {
public:
  I64Expression(long value) : value(value) {}
  long value;
};

class U64Expression : public IntegerExpression {
public:
  U64Expression(unsigned long value) : value(value) {}
  unsigned long value;
};

class I128Expression : public IntegerExpression {
public:
  I128Expression(long value) : value(value) {}
  long value;
};

class U128Expression : public IntegerExpression {
public:
  U128Expression(unsigned long value) : value(value) {}
  unsigned long value;
};

class FloatExpression : public Expression {};

class F32Expression : public FloatExpression {
public:
  F32Expression(float value) : value(value) {}
  float value;
};

class F64Expression : public FloatExpression {
public:
  F64Expression(double value) : value(value) {}
  double value;
};

class F128Expression : public FloatExpression {
public:
  F128Expression(double value) : value(value) {}
  double value;
};

class StringExpression : public Expression {
public:
  StringExpression(std::string value) : value(value) {}
  std::string value;
};

/// 一元表达式
class UnaryExpression : public Expression {
private:
  // ! + -
  char *type;
  /// 目标表达式
  std::unique_ptr<Expression> expr;

public:
  UnaryExpression(char *type, std::unique_ptr<Expression> expr)
      : type(type), expr(std::move(expr)){};

  /// 解析语法树方法
  static std::unique_ptr<UnaryExpression> parseAST();

  llvm::Value *codegen() override;
};

/// 二元表达式
class BinaryExpression : public Expression {
private:
  /// 算术表达式 + - * /
  /// 逻辑表达式 && || and or
  /// 位运算表达式 & | ^ << >>
  /// 比较表达式 == != > >= < <=
  /// 成员表达式 a.b
  /// 索引表达式 a[0]
  char *type;
  /// 左值
  std::unique_ptr<Expression> left;
  /// 右值
  std::unique_ptr<Expression> right;

public:
  BinaryExpression(char *type, std::unique_ptr<Expression> left,
                   std::unique_ptr<Expression> right)
      : type(type), left(std::move(left)), right(std::move(right)){};

  /// 解析语法树方法
  static std::unique_ptr<BinaryExpression>
  parseAST(std::unique_ptr<Expression> left);

  llvm::Value *codegen() override;
};

class BracketExpression : public Expression {
public:
  std::unique_ptr<Expression> expr;
  BracketExpression(std::unique_ptr<Expression> expr) : expr(std::move(expr)){};
};

/// 定义变量语句
class DefineVariableStatement : public Node {
  /// 变量名
  std::string name;
  /// 值类型
  Type type;
  /// 堆引用次数
  unsigned int heap;
  /// 变量值
  std::unique_ptr<Node> value;
};

class VariableValueExpression : public Expression {
private:
  DefineVariableStatement *define;

public:
  VariableValueExpression(DefineVariableStatement *define) : define(define) {}
};

// a.b
class ObjectMemberExpression : public Expression {

private:
  std::unique_ptr<Expression> expr;
  char *name;

public:
  ObjectMemberExpression(std::unique_ptr<Expression> expr, char *name)
      : expr(std::move(expr)), name(name){};
};

// a[1]
class ArrayIndexExpression : public Expression {

private:
  std::unique_ptr<Expression> expr;
  unsigned int index;

public:
  ArrayIndexExpression(std::unique_ptr<Expression> expr, unsigned int index)
      : expr(std::move(expr)), index(index){};
};

/// 函数调用表达式
class FunctionCallExpression : public Expression {};

/// 赋值语句
class AssignStatement : public Node {};

/// 函数声明语句
class FunctionDelclareStatement : public Node {};

/// 定义结构体语句
class DefineStructStatement : public Node {};

/// 定义接口语句
class DefineInterfaceStatment : public Node {};

/// 定义短语语言
class DefinePharseStatement : public Node {};
